using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class Posts : BasePage
{
    #region Page Events
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            tvSiteMap.DataBind();
            if (tvSiteMap.Nodes.Count == 0)
            {
                divNoHomePage.Visible = true;
                dvPost.ChangeMode(DetailsViewMode.Insert);
                divDetails.Visible = true;
            }
        }
    }

    protected override object SaveViewState()
    {
        ViewState["CurrentId"] = currentId;
        ViewState["ContentControlPaths"] = contentControlPaths;
        ViewState["AddPostingParentId"] = addPostingParentId;
        ViewState["UnusedControlPaths"] = unusedControlPaths;
        return base.SaveViewState();
    }

    protected override void LoadViewState(object savedState)
    {
        base.LoadViewState(savedState);
        currentId = ViewState["CurrentId"] as int?;
        contentControlPaths = ViewState["ContentControlPaths"] as Hashtable;
        addPostingParentId = (int)ViewState["AddPostingParentId"];
        unusedControlPaths = ViewState["UnusedControlPaths"] as Hashtable;
    }
    #endregion

    #region Tree View
    protected void tvSiteMap_SelectedNodeChanged(object sender, EventArgs e)
    {
        dvPost.ChangeMode(DetailsViewMode.ReadOnly);
        currentId = int.Parse(tvSiteMap.SelectedNode.Value);
        divDetails.Visible = true;
        divMenus.Visible = true;
        divControls.Visible = true;
        divTopics.Visible = true;
        divUnusedControls.Visible = true;

        dvPost.DataBind();
        cblMenus.DataBind();
        cblTopics.DataBind();
        dlPostControls.EditItemIndex = -1;
        dlPostControls.DataBind();
        dlUnused.DataBind();

    }

    protected void tvSiteMap_TreeNodeDataBound(object sender, TreeNodeEventArgs e)
    {
        if (currentId != null)
        {
            if (e.Node.Value == currentId.Value.ToString())
            {
                e.Node.Selected = true;
            }
        }
    }
    #endregion

    #region page properties
    private int? currentId;
    protected int? CurrentId
    {
        get { return currentId;}
        set { currentId = value; }
    }

    private List<Acms.Bll.PostMenu> menus;
    protected List<Acms.Bll.PostMenu> Menus
    {
        get
        {
            if (menus == null)
            {
                menus = Acms.Bll.PostMenu.GetAllByPostId(CurrentId.Value);
            }
            return menus;
        }
    }
    
    private List<Acms.Bll.PostTopic> topics;
    protected List<Acms.Bll.PostTopic> Topics
    {
        get
        {
            if (topics == null)
            {
                topics = Acms.Bll.PostTopic.GetAllByPostId(CurrentId.Value);
            }
            return topics;
        }
    }

    private List<Acms.Bll.PostControl> GetPostControls()
    {
        return Acms.Bll.PostControl.GetAllByPostId(CurrentId.Value);
    }

    private Hashtable contentControlPaths = new Hashtable();
    #endregion

    #region DataSource
    protected void dsPost_SelectData(object sender, Acms.DataControls.SelectEventArgs<Acms.Bll.Post> e)
    {
        if (currentId != null)
        {
            e.SetData(Acms.Bll.Post.GetById(currentId.Value));
        }
    }

    protected void dsTemplates_SelectData(object sender, Acms.DataControls.SelectEventArgs<Acms.Bll.Template> e)
    {
        e.SetData(Acms.Bll.Template.GetAllBySiteId(AcmsSite.Id));
    }

    protected void dsPost_UpdatingData(object sender, Acms.DataControls.UpdatingDataEventArgs<Acms.Bll.Post> e)
    {
        if (e.Action == Acms.DataControls.UpdateAction.Insert)
        {
            e.Item.ParentId = addPostingParentId;
            e.Item.SiteId = AcmsSite.Id;
        }
        FileUpload fuThumb  = dvPost.FindControl("fuThumb") as FileUpload;
        if (fuThumb != null && fuThumb.HasFile)
        {
            Acms.Bll.File thumb = null;
            if (e.Item.ThumbnailId != null)
            {
                thumb = Acms.Bll.File.GetById(e.Item.ThumbnailId.Value);
            }

            if (thumb == null)
            {
                thumb = Acms.Bll.File.CreateInstance();
            }

            thumb.LoadFileData(Acms.Bll.File.FileTypes.Image, fuThumb.PostedFile, fuThumb.FileBytes);
            thumb.Update();

            e.Item.ThumbnailId = thumb.Id;
        }
    }

    protected void dsMenus_SelectData(object sender, Acms.DataControls.SelectEventArgs<Acms.Bll.Menu> e)
    {
        e.SetData(Acms.Bll.Menu.GetAllBySiteId(AcmsSite.Id));
    }

    protected void dsPostControls_SelectData(object sender, Acms.DataControls.SelectEventArgs<Acms.Bll.PostControl> e)
    {
        e.SetData(GetPostControls());
    }

    protected void dsTopics_SelectData(object sender, Acms.DataControls.SelectEventArgs<Acms.Bll.Topic> e)
    {
        e.SetData(Acms.Bll.Topic.GetAllBySiteId(AcmsSite.Id));
    }
    #endregion

    #region details view
    protected void dvPost_DataBound(object sender, EventArgs e)
    {
        if(dvPost.CurrentMode == DetailsViewMode.Insert)
        {
            if (CurrentId == null)
            {
                //Creating HomePage so diable name field
                TextBox txtNameInsert = dvPost.FindControl("txtNameInsert") as TextBox;
                if (txtNameInsert != null)
                {
                    txtNameInsert.Text = "~";
                    txtNameInsert.Enabled = false;
                }

            }
        }
        else if(dvPost.CurrentMode == DetailsViewMode.Edit)
        {
            if (tvSiteMap.SelectedNode.Parent == null)
            {
                TextBox txtNameEdit = dvPost.FindControl("txtNameEdit") as TextBox;
                if (txtNameEdit != null)
                {
                    txtNameEdit.Enabled = false;
                }
            }
        }
        else if (dvPost.CurrentMode == DetailsViewMode.ReadOnly)
        {
            LinkButton btnMoveUp = dvPost.FindControl("btnMoveUp") as LinkButton;
            if (btnMoveUp != null)
            {
                btnMoveUp.Visible = tvSiteMap.SelectedNode.Parent != null && tvSiteMap.SelectedNode.Parent.ChildNodes[0] != tvSiteMap.SelectedNode;
            }

            LinkButton btnMoveParent = dvPost.FindControl("btnMoveParent") as LinkButton;
            if (btnMoveParent != null)
            {
                btnMoveParent.Visible = tvSiteMap.SelectedNode != null && tvSiteMap.SelectedNode.Parent != null && tvSiteMap.SelectedNode.Parent.Parent != null;
            }

            LinkButton btnAddSibling = dvPost.FindControl("btnAddSibling") as LinkButton;
            if (btnAddSibling != null)
            {
                btnAddSibling.Visible = tvSiteMap.SelectedNode != null && tvSiteMap.SelectedNode.Parent != null;
            }

            Repeater rptSiblings = dvPost.FindControl("rptSiblings") as Repeater;
            if (rptSiblings != null && tvSiteMap.SelectedNode != null)
            {
                TreeNodeCollection tmp = new TreeNodeCollection();
                if (tvSiteMap.SelectedNode != null && tvSiteMap.SelectedNode.Parent != null)
                {
                    foreach (TreeNode node in tvSiteMap.SelectedNode.Parent.ChildNodes)
                    {
                        if (node != tvSiteMap.SelectedNode)
                        {
                            tmp.Add(new TreeNode(node.Text, node.Value));
                        }
                    }
                    if (tmp.Count > 0)
                    {
                        rptSiblings.DataSource = tmp;
                        rptSiblings.DataBind();
                    }
                }
            }
        }
    }

    protected void dvPost_ItemInserted(object sender, DetailsViewInsertedEventArgs e)
    {
        if (e.Exception == null)
        {
            addPostingParentId = 0;
            divNoHomePage.Visible = false;
            currentId = (int)e.Values[Acms.DataControls.PostDataSource.Fields.Id.ToString()];

            tvSiteMap.DataBind();
            cblMenus.DataBind();
            cblTopics.DataBind();
            dlPostControls.EditItemIndex = -1;
            dlPostControls.DataBind();
            dlUnused.DataBind();
        }
    }

    protected void dvPost_ItemDeleted(object sender, DetailsViewDeletedEventArgs e)
    {
        if (e.Exception == null)
        {
            if (tvSiteMap.SelectedNode.Parent == null)
            {
                currentId = null;
                divNoHomePage.Visible = true;
                dvPost.ChangeMode(DetailsViewMode.Insert);
            }
            else
            {
                tvSiteMap.SelectedNode.Parent.Select();
                currentId = int.Parse(tvSiteMap.SelectedNode.Value);
            }
            tvSiteMap.DataBind();
            cblMenus.DataBind();
            cblTopics.DataBind();
            dlPostControls.EditItemIndex = -1;
            dlPostControls.DataBind();
            dlUnused.DataBind();
        }
    }

    protected void btnMoveUp_Click(object sender, EventArgs e)
    {
        if (CurrentId.HasValue && tvSiteMap.SelectedNode != null && tvSiteMap.SelectedNode.Parent != null)
        {
            List<Acms.Bll.Post> tmp = Acms.Bll.Post.GetAllByParentId(int.Parse(tvSiteMap.SelectedNode.Parent.Value));
            for (int i = 1; i < tmp.Count; i++)
            {
                if (tmp[i].Id == CurrentId.Value)
                {
                    tmp[i].Sequence = i - 1;
                    tmp[i - 1].Sequence = i;
                    tmp[i].Update();
                    tmp[i - 1].Update();
                }
            }
            tvSiteMap.DataBind();
            dvPost.DataBind();
        }
    }

    protected void btnMoveParent_Click(object sender, EventArgs e)
    {
        if (CurrentId.HasValue && tvSiteMap.SelectedNode != null && tvSiteMap.SelectedNode.Parent != null && tvSiteMap.Parent.Parent != null)
        {
            Acms.Bll.Post tmp = Acms.Bll.Post.GetById(CurrentId.Value);
            if (tmp != null)
            {
                tmp.ParentId = int.Parse(tvSiteMap.SelectedNode.Parent.Parent.Value);
                tmp.Sequence = tvSiteMap.SelectedNode.Parent.Parent.ChildNodes.Count;
                tmp.Update();
                tvSiteMap.DataBind();
                dvPost.DataBind();
            }
        }
    }

    protected void rptSiblings_ItemCommand(object source, RepeaterCommandEventArgs e)
    {
        if (e.CommandName == "MakeChild")
        {
            Acms.Bll.Post tmp = Acms.Bll.Post.GetById(CurrentId.Value);
            if (tmp != null)
            {
                tmp.ParentId = int.Parse(e.CommandArgument.ToString());
                foreach (TreeNode node in tvSiteMap.SelectedNode.Parent.ChildNodes)
                {
                    if (node.Value == tmp.ParentId.Value.ToString())
                    {
                        tmp.Sequence = node.ChildNodes.Count;
                    }
                }
                tmp.Update();
                tvSiteMap.DataBind();
                dvPost.DataBind();
            }
        }
    }

    protected void dvPost_ItemUpdated(object sender, DetailsViewUpdatedEventArgs e)
    {
        tvSiteMap.DataBind();
        cblMenus.DataBind();
        cblTopics.DataBind();
        dlPostControls.EditItemIndex = -1;
        dlPostControls.DataBind();
        dlUnused.DataBind();
    }
    #endregion

    #region Menus

    protected void btnSaveMenus_Click(object sender, EventArgs e)
    {
        foreach (CheckBox item in cblMenus.Items)
        {
            bool found = false;
            int id = (int)cblMenus.GetValue(item);
            foreach (Acms.Bll.PostMenu menu in Menus)
            {
                if (menu.MenuId == id)
                {
                    if (menu.Included != item.Checked)
                    {
                        menu.Included = item.Checked;
                        menu.Update();
                    }
                    found = true;
                    break;
                }
            }
            if (!found)
            {
                Acms.Bll.PostMenu menu = Acms.Bll.PostMenu.CreateInstance(CurrentId.Value, id, item.Checked);
                menu.Update();
            }
        }
        menus = null;
    }

    private void SetMenuCheckBoxes()
    {
        foreach (Acms.Bll.PostMenu menu in Menus)
        {
            foreach (CheckBox item in cblMenus.Items)
            {
                if ((int)cblMenus.GetValue(item) == menu.MenuId)
                {
                    item.Checked = menu.Included;
                }
            }
        }
    }

    protected void cblMenus_ItemDataBound(object sender, Acms.WebControls.CheckBoxList.ItemDataBoundEventArgs e)
    {
        if (e.Value is int)
        {
            int id = (int)e.Value;
            foreach (Acms.Bll.PostMenu menu in Menus)
            {
                if (menu.MenuId == id)
                {
                    e.Item.Checked = menu.Included;
                }
            }
        }
    }
    #endregion

    #region ContentControls
    protected void dlPostControls_EditCommand(object source, DataListCommandEventArgs e)
    {
        dlPostControls.EditItemIndex = e.Item.ItemIndex;
        dlPostControls.DataBind();
    }

    protected void dlPostControls_ItemDataBound(object sender, DataListItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.EditItem || e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            Acms.Bll.PostControl postCtrl = e.Item.DataItem as Acms.Bll.PostControl;
            Label lblError = e.Item.FindControl("lblError") as Label;
            PlaceHolder phControl = e.Item.FindControl("phControl") as PlaceHolder;
            if (!string.IsNullOrEmpty(postCtrl.AdminControlType))
            {
                try
                {
                    Acms.AcmsControls.BaseContentControlEdit ctrl = Page.LoadControl(System.Type.GetType(postCtrl.AdminControlType, true, true), null) as Acms.AcmsControls.BaseContentControlEdit;
                    if (ctrl != null)
                    {
                        ctrl.State = e.Item.ItemType == ListItemType.EditItem ? Acms.AcmsControls.BaseContentControlEdit.States.Edit : Acms.AcmsControls.BaseContentControlEdit.States.Display;
                        contentControlPaths[e.Item.ItemIndex] = postCtrl.AdminControlType;
                        phControl.Controls.Add(ctrl);
                        ctrl.LoadData(postCtrl);
                        ctrl.DataBind();
                    }
                    else
                    {
                        lblError.Text = string.Format("Faild to load control '{0}' as a 'Acms.AcmsControls.BaseAdminContentControl", postCtrl.AdminControlType);
                        lblError.Visible = true;
                    }
                }
                catch (System.IO.FileNotFoundException ex)
                {
                    lblError.Text = ex.Message;
                    lblError.Visible = true;
                }
            }
        }
    }

    protected void dlPostControls_ItemCreated(object sender, DataListItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.EditItem || e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            PlaceHolder phControl = e.Item.FindControl("phControl") as PlaceHolder;
            if (phControl != null && contentControlPaths[e.Item.ItemIndex] is string)
            {
                Control ctrl = Page.LoadControl(System.Type.GetType(contentControlPaths[e.Item.ItemIndex] as string, true, true), null);
                if (ctrl != null)
                {
                    phControl.Controls.Add(ctrl);
                }
            }
        }
    }

    protected void dlPostControls_DataBinding(object sender, EventArgs e)
    {
        contentControlPaths = new Hashtable();
    }

    protected void dlPostControls_CancelCommand(object source, DataListCommandEventArgs e)
    {
        dlPostControls.EditItemIndex = -1;
        dlPostControls.DataBind();
    }

    protected void dlPostControls_UpdateCommand(object source, DataListCommandEventArgs e)
    {
        PlaceHolder phControl = e.Item.FindControl("phControl") as PlaceHolder;
        Acms.Bll.PostControl postControl = GetPostControls()[e.Item.ItemIndex];
        Acms.AcmsControls.BaseContentControlEdit ctrl = phControl.Controls[0] as Acms.AcmsControls.BaseContentControlEdit;

        if (ctrl != null)
        {
            ctrl.SaveData(postControl);
        }
        dlPostControls.EditItemIndex = -1;
        dlPostControls.DataBind();
    }

    protected void dlPostControls_DeleteCommand(object source, DataListCommandEventArgs e)
    {
        PlaceHolder phControl = e.Item.FindControl("phControl") as PlaceHolder;
        Acms.Bll.PostControl postControl = GetPostControls()[e.Item.ItemIndex];
        Acms.AcmsControls.BaseContentControlEdit ctrl = phControl.Controls[0] as Acms.AcmsControls.BaseContentControlEdit;

        if (ctrl != null)
        {
            ctrl.DeleteData(postControl);
        }

        dlPostControls.EditItemIndex = -1;
        dlPostControls.DataBind();
    }

    #endregion

    protected void cblTopics_ItemDataBound(object sender, Acms.WebControls.CheckBoxList.ItemDataBoundEventArgs e)
    {
        Acms.Bll.Topic topic = e.DataItem as Acms.Bll.Topic;
        if(topic != null)
        {
            foreach (Acms.Bll.PostTopic postTopic in Topics)
            {
                if (postTopic.TopicId == topic.Id)
                {
                    e.Item.Checked = true;
                }
            }
        }
    }

    protected void btnSaveTopics_Click(object sender, EventArgs e)
    {
        foreach (CheckBox item in cblTopics.Items)
        {
            bool included = false;
            int id = (int)cblTopics.GetValue(item);
            foreach (Acms.Bll.PostTopic topic in Topics)
            {
                if (topic.TopicId == id)
                {
                    included = true;
                }
            }
            if (included && !item.Checked)
            {
                foreach (Acms.Bll.PostTopic topic in Topics)
                {
                    if (topic.TopicId == id)
                    {
                        topic.Delete();
                    }
                }
            }
            else if (!included && item.Checked)
            {
                Acms.Bll.PostTopic topic = Acms.Bll.PostTopic.CreateInstance(CurrentId.Value, id);
                topic.Update();
            }
        }
        topics = null;
    }

    private int addPostingParentId;

    protected void dvPost_ItemCommand(object sender, DetailsViewCommandEventArgs e)
    {
        if (e.CommandName == "AddSibling")
        {
            addPostingParentId = int.Parse(tvSiteMap.SelectedNode.Parent.Value);
            dvPost.ChangeMode(DetailsViewMode.Insert);
            dvPost_ModeChanged(dvPost, EventArgs.Empty);
        }
        else if (e.CommandName == "AddChild")
        {
            addPostingParentId = int.Parse(tvSiteMap.SelectedNode.Value);
            dvPost.ChangeMode(DetailsViewMode.Insert);
            dvPost_ModeChanged(dvPost, EventArgs.Empty);
        }
    }
    protected void dvPost_ModeChanged(object sender, EventArgs e)
    {
        if (dvPost.CurrentMode == DetailsViewMode.Insert)
        {
            divControls.Visible = false;
            divMenus.Visible = false;
            divTopics.Visible = false;
            divUnusedControls.Visible = false;
        }
        else
        {
            divControls.Visible = true;
            divMenus.Visible = true;
            divTopics.Visible = true;
            divUnusedControls.Visible = true;
        }
    }

    protected void dsUnused_SelectData(object sender, Acms.DataControls.SelectEventArgs<Acms.Bll.UnusedPostControl> e)
    {
        e.SetData(Acms.Bll.UnusedPostControl.GetAllByPostId(CurrentId.Value));
    }

    private Hashtable unusedControlPaths = new Hashtable();

    protected void dlUnused_ItemCreated(object sender, DataListItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.EditItem || e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            PlaceHolder phControl = e.Item.FindControl("phControl") as PlaceHolder;
            if (phControl != null && unusedControlPaths[e.Item.ItemIndex] is string)
            {
                Control ctrl = Page.LoadControl(System.Type.GetType(unusedControlPaths[e.Item.ItemIndex] as string, true, true), null);
                if (ctrl != null)
                {
                    phControl.Controls.Add(ctrl);
                }
            }
        }
    }

    protected void dlUnused_ItemDataBound(object sender, DataListItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.EditItem || e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            Acms.Bll.UnusedPostControl postCtrl = e.Item.DataItem as Acms.Bll.UnusedPostControl;
            Label lblError = e.Item.FindControl("lblError") as Label;
            PlaceHolder phControl = e.Item.FindControl("phControl") as PlaceHolder;
            if (!string.IsNullOrEmpty(postCtrl.AdminControlType))
            {
                try
                {
                    Acms.AcmsControls.BaseContentControlEdit ctrl = Page.LoadControl(System.Type.GetType(postCtrl.AdminControlType, true, true), null) as Acms.AcmsControls.BaseContentControlEdit;
                    if (ctrl != null)
                    {
                        ctrl.State = Acms.AcmsControls.BaseContentControlEdit.States.Display;
                        unusedControlPaths[e.Item.ItemIndex] = postCtrl.AdminControlType;
                        phControl.Controls.Add(ctrl);
                        ctrl.LoadData(postCtrl);
                        ctrl.DataBind();
                    }
                    else
                    {
                        lblError.Text = string.Format("Faild to load control '{0}' as a 'Acms.AcmsControls.BaseAdminContentControl", postCtrl.AdminControlType);
                        lblError.Visible = true;
                    }
                }
                catch (System.IO.FileNotFoundException ex)
                {
                    lblError.Text = ex.Message;
                    lblError.Visible = true;
                }
            }
        }
    }

    protected void dlUnused_DataBinding(object sender, EventArgs e)
    {
        unusedControlPaths = new Hashtable();
    }
}
